﻿using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;

namespace Milan.Net
{
	public class UploadDirectory
	{
		/// <summary>
		/// Watches an upload directory and sends the files there up to the server.
		/// It includes the extra given post data with each upload.
		/// It works with the remote uploader php script.
		/// </summary>
		public UploadDirectory( string newDirectory, string oldDirectory, Uri remoteAcceptorUri, NameValueCollection postData )
		{
			m_newDirectory = newDirectory;
			m_oldDirectory = oldDirectory;
			m_remoteAcceptorUri = remoteAcceptorUri;
			m_postData = postData;
		}

		/// <summary>
		/// Blocking call: waits for a file to appear in the input directory, or for the quit event.
		/// </summary>
		/// <returns>Always returns true, because the quite event was received.</returns>
		public void StartWatching()
		{
	//		var inPath = Path.GetFullPath(Configuration.File.InPath);
			FileSystemWatcher watcher = new FileSystemWatcher(m_newDirectory, "*.*");
			watcher.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite | NotifyFilters.FileName | NotifyFilters.DirectoryName;
			watcher.Changed += new FileSystemEventHandler(OnChanged);
			watcher.Created += new FileSystemEventHandler(OnChanged);
			watcher.Renamed += new RenamedEventHandler(OnRenamed);
			watcher.EnableRaisingEvents = true;
			quitEvent = new System.Threading.AutoResetEvent(false);
			do
			{
				try
				{
					foreach (var file in Directory.GetFiles(m_newDirectory, "*.*"))
					{
						if (Milan.Net.Upload.PostFile(m_remoteAcceptorUri, file, m_postData).StartsWith("ok:"))
						{
							var dest = Path.Combine(m_oldDirectory, Path.GetFileName(file));
							if (File.Exists(dest))
								File.Delete(dest);
							File.Move(file, dest);
						}
					}
				}
				catch (Exception)
				{
					// We should log the error here to the log file.
				}
			} while (!quitEvent.WaitOne(100000));	// Wait until the quit event is signaled -- Every 100 000 try to send all the files again
		}

		/// <summary>
		/// Called indirectly from WatchTheInDirectory when a file comes in
		/// </summary>
		/// <param name="source"></param>
		/// <param name="e"></param>
		private void OnChanged(object source, FileSystemEventArgs e)
		{
			UploadFile(e.FullPath);
		}

		/// <summary>
		/// Called indirectly from WatchTheInDirectory when a file moves into the in directory
		/// </summary>
		/// <param name="source"></param>
		/// <param name="e"></param>
		private void OnRenamed(object source, RenamedEventArgs e)
		{
			UploadFile(e.FullPath);
		}
		private void UploadFile(string filePath)
		{
			Milan.Net.Upload.PostFile(m_remoteAcceptorUri, filePath, m_postData);
		}
		private string m_newDirectory;
		private string m_oldDirectory;
		private Uri m_remoteAcceptorUri;
		private NameValueCollection m_postData;
		// Allows us to quit gracefully.
		private System.Threading.AutoResetEvent quitEvent;
		public System.Threading.AutoResetEvent QuitEvent { get { return quitEvent; } }

	}
}
